package com.bcxj.apipassenger.Service;

import com.bcxj.apipassenger.remote.ServicePassengerUserClient;
import com.bcxj.apipassenger.remote.ServiceVerificationcodeClient;

import com.bcxj.internalcommon.constant.CommonStatusEnum;
import com.bcxj.internalcommon.constant.IdentityConstant;
import com.bcxj.internalcommon.constant.TokenConstant;
import com.bcxj.internalcommon.dto.ResponseResult;
import com.bcxj.internalcommon.dto.VerificationCodeDTO;
import com.bcxj.internalcommon.response.NumberCodeResponse;
import com.bcxj.internalcommon.response.TokenResponse;
import com.bcxj.internalcommon.util.JwtUtils;
import com.bcxj.internalcommon.util.RedisPrefixUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * ClassName: VerfivcationCodeService
 * Package: com.bcxj.Service
 * Description:
 */
@Service
public class VerfivcationCodeService {

    @Autowired
    private ServiceVerificationcodeClient serviceVerificationcodeClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ServicePassengerUserClient servicePassengerUserClient;

    /**
     * 手机验证码生成
     *
     * @param passengerPhone
     * @return 返回JSON格式化数据
     */
    public ResponseResult generatorCode(String passengerPhone) {
        // 调用验证码服务
        System.out.print("生成验证码：");

        ResponseResult<NumberCodeResponse> result = serviceVerificationcodeClient.numberCode(6);// 这个需要调用其他的服务的

        System.out.println("调用服务获取的验证码为：" + result.getData().getNumberCode());

        // 写入Redis. 设置为30天过期
        redisTemplate.opsForValue().set(RedisPrefixUtils.generatorKeyByPhone(passengerPhone, IdentityConstant.PASSENGER_IDENTITY), result.getData().getNumberCode(), 2, TimeUnit.MINUTES);

        // 调用其他的第三方接口，发送验证码
        return ResponseResult.success();
    }

    /**
     * 校验验证码
     * @param verificationCodeDTO 验证码实体类
     * @return
     */
    public ResponseResult<TokenResponse> checkCode(VerificationCodeDTO verificationCodeDTO) {
        System.out.println("效验的手机号: " + verificationCodeDTO.getPassengerPhone());
        System.out.println("输入的验证码：" + verificationCodeDTO.getVerificationCode());

        // 1 获取Redis的数据
        String key = RedisPrefixUtils.generatorKeyByPhone(verificationCodeDTO.getPassengerPhone(), IdentityConstant.PASSENGER_IDENTITY);
        String code = redisTemplate.opsForValue().get(key);
        System.out.println("验证码Code：" + code);

        // 2 与Redis的进行比对
        // 2.1 不存在数据
        // 验证码过期
        if(StringUtils.isBlank(code)) {
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_OVERDUE.getCode(), CommonStatusEnum.VERIFICATION_CODE_OVERDUE.getMessage());
        }
        // 2.2 存在数据
        // 2.2.1 不匹配
        // 输入验证码不正确
        if(!code.equals(verificationCodeDTO.getVerificationCode().trim())){
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode(), CommonStatusEnum.VERIFICATION_CODE_ERROR.getMessage());
        }

        // 2.2.2 匹配
        //效验成功，检测用户是否为新用户，是就创建新用户, 调用服务service-passenger-user
        servicePassengerUserClient.loginOrRegister(verificationCodeDTO);

        // 3 生成并返回accesstoken
        String accessToken = JwtUtils.generatorToken(verificationCodeDTO.getPassengerPhone(), IdentityConstant.PASSENGER_IDENTITY, TokenConstant.ACCESS_TOKEN);
        String refreshToken = JwtUtils.generatorToken(verificationCodeDTO.getPassengerPhone(), IdentityConstant.PASSENGER_IDENTITY, TokenConstant.REFRESH_TOKEN);
        // 3. token存入Redis中的数据
        String accessTokenKey = RedisPrefixUtils.generatorTokenKey(verificationCodeDTO.getPassengerPhone(), IdentityConstant.PASSENGER_IDENTITY, TokenConstant.ACCESS_TOKEN);
        String refreshTokenKey = RedisPrefixUtils.generatorTokenKey(verificationCodeDTO.getPassengerPhone(), IdentityConstant.PASSENGER_IDENTITY, TokenConstant.REFRESH_TOKEN);
        redisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 1, TimeUnit.DAYS);

        // 3.2 返回token
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }

}
